package com.cgl.until;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Properties;

// 密码加密
public class SHA256PasswordEncryption {

    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SHA256PasswordEncryption.class);

    // 加载密钥
    private static String loadSalt() {
        // 创建Properties对象，用于存储配置文件中的键值对
        Properties properties = new Properties();
        try {
            // 使用JwtUtil类的类加载器加载配置文件jwt.properties
            // 这个方法会返回一个输入流，用于读取配置文件内容
            //这里的jwt.properties是密钥
            InputStream inputStream = JwtUntil.class.getClassLoader().getResourceAsStream("application.properties");

            // 检查输入流是否为null，如果是，则表示配置文件未找到
            if (inputStream == null) {
                // 抛出FileNotFoundException，表示配置文件未找到
                throw new FileNotFoundException("配置文件application.properties未找到");
            }

            // 使用Properties对象加载输入流中的配置信息
            properties.load(inputStream);

            // 从Properties对象中获取名为"Salt"的属性值
            // 这个值是从配置文件中读取的密钥
            String Salt = properties.getProperty("Salt");

            // 检查获取到的密钥是否为空或null
            if (Salt == null || Salt.isEmpty()) {
                // 如果密钥未被正确指定，抛出IllegalArgumentException
                throw new IllegalArgumentException("配置文件中未指定secretKey");
            }

            // 如果一切正常，返回配置文件中指定的密钥
            return Salt;
        } catch (FileNotFoundException e) {
            // 如果配置文件未找到，记录错误日志，并抛出运行时异常
            logger.error("配置文件application.properties未找到", e);
            throw new RuntimeException("配置文件加载失败，无法启动应用", e);
        } catch (IllegalArgumentException e) {
            // 如果配置文件中未指定密钥，记录错误日志，并抛出运行时异常
            logger.error("Salt", e);
            throw new RuntimeException("配置文件加载失败，无法启动应用", e);
        } catch (Exception e) {
            // 捕获其他所有异常，记录错误日志，并抛出运行时异常
            // 这包括了Properties加载过程中可能发生的任何异常
            logger.error("密钥验证失败", e);
            throw new RuntimeException("密钥加载失败，无法启动应用", e);
        }
    }

    /**
     * 哈希密码
     * @param password // 待哈希的密码
     * @return
     */
    public String hashPassword(String password) {
        try {
            // 将密码和盐值拼接
            String saltedPassword = password + loadSalt();

            int iterations=1000;

            // 获取SHA-256 MessageDigest实例
            MessageDigest digest = MessageDigest.getInstance("SHA-256");

            // 多轮哈希
            byte[] hashBytes = digest.digest(saltedPassword.getBytes());
            for (int i = 1; i < iterations; i++) {
                hashBytes = digest.digest(hashBytes);
            }

            // 将哈希结果转换为Base64字符串
            return Base64.getEncoder().encodeToString(hashBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 algorithm not found", e);
        }
    }

    /**
     *  验证密码
     * @param password // 待验证的密码
     * @param hashedPassword // 已哈希的密码
     * @return
     */
    public boolean verifyPassword(String password, String hashedPassword) {
        String newHashedPassword = hashPassword(password);
        return newHashedPassword.equals(hashedPassword);
    }
}
